package com.pni.games.poker.hands;

import com.pni.game.cards.Card;

public abstract class PokerHand implements Comparable<PokerHand> {
	
	public enum HandType {
		
		HIGH_CARD (1),
		PAIR (2),
		TWO_PAIR (3),
		THREE_OF_A_KIND (4),
		STRAIGHT (5),
		FLUSH (6),
		FULL_HOUSE (7),
		FOUR_OF_A_KIND (8),
		STRAIGHT_FLUSH (9);
		
		private int handValue;
		
		HandType(int handValue){
			this.handValue = handValue;
		}
		
		public int value(){
			return handValue;
		}
		
	}
	
	public static final int POKER_HAND_SIZE = 5;
	private HandType handType;

	protected Card[] cards;
	
	public PokerHand(Card[] cards, HandType handType) {
		if(cards.length != POKER_HAND_SIZE){
			throw new IllegalArgumentException("A Poker hand must consist of exactly 5 cards");
		}
		this.cards = cards;
		this.handType = handType;
		determineHandValue();
	}

	public int compareTo(PokerHand otherHand) {
		if(handType.value() > otherHand.getHandType().value()){
			return 1;
		} else if (handType.equals(otherHand.handType)) {
			return compareSameHand(otherHand);
		} else {
			return -1;
		}
		
	}
	
	public HandType getHandType() {
		return handType;
	}
	
	protected abstract int compareSameHand(PokerHand otherHand);
	
	/**
	 * This method is used to determine a hands value in the case of a tie.  It is important that the value of the different cards
	 * in a hand be set so that they can be used to accurately determine the winner when comparing hands.
	 * Should throw an IAE if a hand is not valid.
	 */
	protected abstract void determineHandValue() throws IllegalArgumentException;

}
